package org.ktx.osr.util

import android.annotation.SuppressLint
import android.os.Build
import android.view.SurfaceControl
import android.view.View
import androidx.annotation.RequiresApi

/**
 * 让某个Window的SurfaceControl不显示在截图中，代码是根据Android13写的，注意兼容性和权限问题
 */
@RequiresApi(Build.VERSION_CODES.Q)
@SuppressLint("PrivateApi", "DiscouragedPrivateApi")
fun View.skipScreenShot() {
    try {
        val windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal")
        val getInstanceMethod = windowManagerGlobalClass.getDeclaredMethod("getInstance")
        getInstanceMethod.isAccessible = true
        val windowManagerGlobal = getInstanceMethod.invoke(null)
        val mRootsField = windowManagerGlobalClass.getDeclaredField("mRoots")
        mRootsField.isAccessible = true
        val mRoots = mRootsField.get(windowManagerGlobal) as? List<*>
        val viewRootImpl = mRoots?.firstOrNull { root ->
            val viewRootImplClass = root!!::class.java
            val mViewField = viewRootImplClass.getDeclaredField("mView")
            mViewField.isAccessible = true
            val mView = mViewField.get(root)
            mView === this
        }
        val viewRootImplClass = viewRootImpl!!::class.java
        val getSurfaceControlMethod =
            viewRootImplClass.getDeclaredMethod("getSurfaceControl")
        getSurfaceControlMethod.isAccessible = true
        val surfaceControl =
            getSurfaceControlMethod.invoke(viewRootImpl) as? SurfaceControl
        if (surfaceControl != null && surfaceControl.isValid) {
            val transaction = SurfaceControl.Transaction()
            transaction.use { t ->
                val method = t::class.java.getDeclaredMethod(
                    "setSkipScreenshot",
                    SurfaceControl::class.java,
                    Boolean::class.javaPrimitiveType
                )
                method.isAccessible = true
                method.invoke(t, surfaceControl, true)
                t.apply()
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}